package com.rabbit.eap.system.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.rabbit.eap.common.lang.StringUtils;
import com.rabbit.eap.framework.common.api.ApiResult;
import com.rabbit.eap.framework.common.enums.MsgEnum;
import com.rabbit.eap.framework.common.exception.EapException;
import com.rabbit.eap.framework.common.service.impl.BaseServiceImpl;
import com.rabbit.eap.framework.core.pagination.PageInfo;
import com.rabbit.eap.framework.core.pagination.Paging;
import com.rabbit.eap.system.dto.SysPostDTO;
import com.rabbit.eap.system.entity.SysPost;
import com.rabbit.eap.system.entity.SysUserDept;
import com.rabbit.eap.system.entity.SysUserPost;
import com.rabbit.eap.system.enums.PostStateEnum;
import com.rabbit.eap.system.mapper.SysPostMapper;
import com.rabbit.eap.system.mapper.SysUserDeptMapper;
import com.rabbit.eap.system.mapper.SysUserPostMapper;
import com.rabbit.eap.system.param.SysPostPageParam;
import com.rabbit.eap.system.service.ISysPostService;
import com.rabbit.eap.system.vo.SysPostVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;

/**
 * @projectName: eap
 * @packageName: com.rabbit.eap.system.service.impl
 * @className SysPostServiceImpl
 * @author： rabbit
 * @version： 1.0
 * @since： 2020/06/06 23:34:03
 * <p>Description:
 * 岗位信息表 服务实现类
 * </p>

 */
@Slf4j
@Service
public class SysPostServiceImpl extends BaseServiceImpl<SysPostMapper, SysPost> implements ISysPostService {

    @Autowired
    private SysPostMapper sysPostMapper;

    @Autowired
    private SysUserPostMapper sysUserPostMapper;

    @Autowired
    private SysUserDeptMapper sysUserDeptMapper;

    /**
     * @param sysPostDTO:sysPostDTO数据传输对象
     * @throws Exception
     * @Description: 添加岗位信息表
     * @methodName: saveSysPost
     * @return: ApiResult
     * @date: 2020/06/06 23:34:03
     * @author: rabbit
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public ApiResult saveSysPost(SysPostDTO sysPostDTO) throws Exception {
        checkPost(sysPostDTO);
        SysPost sysPost = sysPostDTO.convert(SysPost.class);
        boolean bool = super.save(sysPost);
        if (bool) {
            return ApiResult.ok(MsgEnum.ADD_SUCCESS.getDesc());
        } else {
            return ApiResult.fail(MsgEnum.ADD_FAIL.getDesc());
        }
    }

    /**
     * @param sysPostDTO:sysPostDTO数据传输对象
     * @throws Exception
     * @Description 修改岗位信息表
     * @methodName: modifySysPost
     * @return: ApiResult
     * @date: 2020/06/06 23:34:03
     * @author: rabbit
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public ApiResult modifySysPost(SysPostDTO sysPostDTO) throws Exception {
        checkPost(sysPostDTO);
        SysPost sysPost = sysPostDTO.convert(SysPost.class);
        boolean bool = super.updateById(sysPost);
        if (bool) {
            return ApiResult.ok(MsgEnum.UPDATE_SUCCESS.getDesc());
        } else {
            return ApiResult.fail(MsgEnum.UPDATE_FAIL.getDesc());
        }
    }

    /**
     * @param sysPostDTO:
     * @Description: 保存/修改公用校验方法
     * @methodName: checkPost
     * @return: com.rabbit.eap.framework.common.api.ApiResult
     * @date: 2020/10/4 09:39
     * @author: rabbit
     */
    private ApiResult checkPost(SysPostDTO sysPostDTO) {
        boolean codeUnique = this.checkPostCodeUnique(sysPostDTO);
        boolean nameUnique = this.checkPostNameUnique(sysPostDTO);
        if (codeUnique || nameUnique) {
            return ApiResult.fail(String.format(PostStateEnum.POST_HAS_EXIST.getDesc(), sysPostDTO.getPostCode()));
        }
        return null;
    }

    /**
     * @param ids:ids集合
     * @throws Exception
     * @Description 删除岗位信息表
     * @methodName: removeSysPost
     * @return: ApiResult
     * @date: 2020/06/06 23:34:03
     * @author: rabbit
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public ApiResult removeSysPost(Long[] ids) throws Exception {
        for (Long postId : ids) {
            SysPost sysPost = sysPostMapper.selectById(postId);
            if (checkPostCount(sysPost.getId())) {
                throw new EapException(String.format(PostStateEnum.CAN_NOT_DELETE.getDesc(), sysPost.getPostName()));
            }
        }
        boolean bool = super.removeByIds(Arrays.asList(ids));
        if (bool) {
            return ApiResult.ok(MsgEnum.DELETE_SUCCESS.getDesc());
        } else {
            return ApiResult.fail(MsgEnum.DELETE_FAIL.getDesc());
        }
    }

    /**
     * @param id: id
     * @throws Exception
     * @Description 根据Id获取岗位信息表详情
     * @methodName: getSysPostInfo
     * @return: ApiResult
     * @date: 2020/06/06 23:34:03
     * @author: rabbit
     */
    @Override
    public ApiResult getSysPostById(Long id) throws Exception {
        if (ObjectUtil.isNull(id)) {
            return ApiResult.fail(MsgEnum.PARAM_NOT_NULL.getDesc());
        }
        SysPost sysPost = super.getById(id);
        SysPostVO sysPostVO = sysPost.convert(SysPostVO.class);
        return ApiResult.ok(sysPostVO);
    }

    /**
     * @param sysPostPageParam
     * @throws Exception
     * @Description 岗位信息表分页列表
     * @methodName: getSysPostPageList
     * @return: ApiResult
     * @date: 2020/06/06 23:34:03
     * @author: rabbit
     */
    @Override
    public ApiResult getSysPostPageList(SysPostPageParam sysPostPageParam) throws Exception {
        Page<SysPost> page = new PageInfo<>(sysPostPageParam, OrderItem.desc(getLambdaColumn(SysPost::getSort)));
        QueryWrapper<SysPost> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(StringUtils.isNotBlank(sysPostPageParam.getPostCode()), SysPost::getPostCode, sysPostPageParam.getPostCode())
                .eq(StringUtils.isNotBlank(sysPostPageParam.getPostName()), SysPost::getPostName, sysPostPageParam.getPostName())
                .eq(StringUtils.isNotBlank(sysPostPageParam.getStatus()), SysPost::getStatus, sysPostPageParam.getStatus());

        IPage<SysPostVO> iPage = sysPostMapper.selectPage(page, queryWrapper)
                .convert(sysPost -> sysPost.convert(SysPostVO.class));
        Paging<SysPostVO> paging = new Paging<SysPostVO>(iPage);
        return ApiResult.ok(paging);
    }

    /**
     * @param postId: 岗位id
     * @Description 查看岗位使用数量
     * @methodName: checkPostCount
     * @return: boolean
     * true:已经被使用 false:未被使用
     * @date: 2020/6/5 22:55
     * @author: rabbit
     */
    private boolean checkPostCount(Long postId) {
        boolean flag = false;
        QueryWrapper<SysUserPost> userPostQueryWrapper = new QueryWrapper<>();
        QueryWrapper<SysUserDept> userDeptQueryWrapper = new QueryWrapper<>();
        userPostQueryWrapper.lambda().eq(SysUserPost::getPostId, postId);
        userDeptQueryWrapper.lambda().eq(SysUserDept::getPostId, postId);
        int selectCount = sysUserPostMapper.selectCount(userPostQueryWrapper);
        int count = sysUserDeptMapper.selectCount(userDeptQueryWrapper);
        if (selectCount > 0 || count > 0) {
            flag = true;
        }
        return flag;
    }

    /**
     * @param sysPostDTO: 岗位数据传输对象
     * @Description 校验岗位编码是否唯一
     * @methodName: checkPostCodeUnique
     * @return: boolean
     * true:重复  false:不重复
     * @date: 2020/6/5 23:04
     * @author: rabbit
     */
    private boolean checkPostCodeUnique(SysPostDTO sysPostDTO) {
        Long postId = ObjectUtil.isEmpty(sysPostDTO.getId()) ? -1L : sysPostDTO.getId();
        String postCode = sysPostDTO.getPostCode();
        SysPost sysPost = sysPostMapper.selectOne(new QueryWrapper<SysPost>().lambda().eq(SysPost::getPostCode, postCode));
        boolean bool = ObjectUtil.isNotNull(sysPost) && sysPost.getId().longValue() != postId.longValue();
        if (bool) {
            return true;
        }
        return false;
    }

    /**
     * @param sysPostDTO: 岗位数据传输对象
     * @Description 检验岗位名称是否唯一
     * @methodName: checkPostNameUnique
     * @return: boolean
     * true:重复  false:不重复
     * @date: 2020/6/5 23:08
     * @author: rabbit
     */
    private boolean checkPostNameUnique(SysPostDTO sysPostDTO) {
        Long postId = ObjectUtil.isEmpty(sysPostDTO.getId()) ? -1L : sysPostDTO.getId();
        String postName = sysPostDTO.getPostName();
        SysPost sysPost = sysPostMapper.selectOne(new QueryWrapper<SysPost>().lambda().eq(SysPost::getPostName, postName));
        boolean bool = ObjectUtil.isNotNull(sysPost) && sysPost.getId().longValue() != postId.longValue();
        if (bool) {
            return true;
        }
        return false;
    }

    /**
     * @param sysPostDTO:
     * @Description: 修改岗位状态
     * @methodName: changeStatus
     * @return: com.rabbit.eap.framework.common.api.ApiResult
     * @date: 2020/10/4 10:55
     * @author: rabbit
     */
    @Override
    public ApiResult changeStatus(SysPostDTO sysPostDTO) {
        SysPost sysPost = new SysPost().setId(sysPostDTO.getId()).setStatus(sysPostDTO.getStatus());
        boolean bool = updateById(sysPost);
        if (bool) {
            return ApiResult.ok(MsgEnum.UPDATE_SUCCESS.getDesc());
        } else {
            return ApiResult.fail(MsgEnum.UPDATE_FAIL.getDesc());
        }
    }
    /**
     * @Description: 获取所有可用的岗位
     * @methodName: getAllPost
     * @param :
     * @return: com.rabbit.eap.framework.common.api.ApiResult
     * @date: 2020/10/28 09:27
     * @author: rabbit
     *
     */
    @Override
    public ApiResult getAllPost() {
        QueryWrapper<SysPost> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SysPost::getStatus, StringPool.ZERO);
        List<SysPost> list = sysPostMapper.selectList(queryWrapper);
        return ApiResult.ok(list);
    }
}
